import { FC, ReactNode } from 'react';
import styles from './d3-demo1.module.less';

export interface D3Demo1Props {
    children?: ReactNode;
}

// 归一化
const normalized = (arr: Float32Array) => {
    let sum = 0;
    for (let i = 0; i < arr.length; i++) {
        sum += arr[i] * arr[i];
    }

    const q = Math.sqrt(sum);
    const results = [];
    for (let i = 0; i < arr.length; i++) {
        results[i] = arr[i] / q;
    }

    return results;
};

// 叉积函数，得到一个新向量，方向和输入的两个向量垂直
const cross = (a: Float32Array, b: Float32Array): Float32Array => {
    return new Float32Array([
        a[1] * b[1] - a[2] * b[1],
        a[2] * b[0] - a[0] * b[2],
        a[0] * b[1] - a[1] * b[0]
    ]);
};

// 点击函数 获取投影长度
const dot = (a: Float32Array, b: Float32Array): number => {
    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
};

// 向量差
const minus = (a: Float32Array, b: Float32Array): Float32Array => {
    return new Float32Array([
        a[0] - b[0],
        a[1] - b[1],
        a[2] - b[2]
    ]);
};

// 视图矩阵获取
const getViewMatrix = (eyex, eyey, eyez, lookAtx, lookAty, lookAtz, upx, upy, upz) => {
    // 视点
    const eye = new Float32Array([eyex, eyey, eyez]);
    // 目标点
    const lookAt = new Float32Array([lookAtx, lookAty, lookAtz]);
    // 上方向
    const up = new Float32Array([upx, upy, upz]);
    // 确定z轴
    const z = minus(eye, lookAt);
    // todo 这里需要改造，直接修改z
    normalized(z);
    normalized(up);

    const x = cross(z, up);

    normalized(x);

    const y = cross(x, z);

    return new Float32Array([
        x[0], y[0], z[0], 0,
        x[1], y[1], z[1], 0,
        x[2], y[2], z[2], 0,
        -dot(x, eye), -dot(y, eye), -dot(z, eye), 1
    ]);
};

const D3Demo1: FC<D3Demo1Props> = () => {
    return (
        <div className={styles.d3Demo1}>
            D3Demo1
        </div>
    );
};

export default D3Demo1;
